<?php

namespace App\Console\Commands\Plane\Rules;

use App\Models\Plane\Rules\PlaneChangeRule;
use App\Models\Plane\Rules\PlaneRefundRule;
use Illuminate\Console\Command;
use Illuminate\Support\Str;
use Laravel\Octane\Exceptions\DdException;
use Maatwebsite\Excel\Facades\Excel;

class PlaneRCRulesImport extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'plane.rc_rules:import';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Execute the console command.
     *
     * @return int
     * @throws DdException
     */
    public function handle()
    {
        $time_rules = [

        ];
        $excel      = Excel::toArray(collect(), storage_path('plane/seeds/rc_condition.xlsx'));
        $data       = $excel[0];
        unset($data[0]);
        $conditions         = $data;
        $time_rules_columns = range(7, 12);
        foreach ($conditions as $condition) {
            $trs = [];
            foreach ($time_rules_columns as $column) {
                if ($condition[$column]) {
                    $trs[] = [
                        'time' => $this->parseTime($condition[$column]),
                        'desc' => $condition[$column - 6],
                    ];
                }
            }
            $time_rules[$condition[0]] = $trs;
        }

        // 第二步 读取规则

        $excel_rc = Excel::toArray(collect(), storage_path('plane/seeds/rc_rules.xlsx'));
        $free     = 0;
        $datas    = $excel_rc[0];
        unset($datas[0], $datas[1], $datas[2]);
        $column_company_name            = 0;
        $column_carrier_code            = 1;
        $column_rule                    = 3;
        $column_airport_name            = 5;
        $column_ticket_type             = 6;
        $column_cabin_name              = 7;
        $column_cabins                  = 8;
        $column_discount                = 9;
        $column_adult_refund_rules      = [10, 15];
        $column_adult_change_rules      = [16, 21];
        $column_adult_refund_rate_start = 10;
        $column_adult_change_rate_start = 16;
        $column_child_refund_rate_start = 22;
        $column_child_change_rate_start = 28;
        $column_child_refund_rules      = [22, 27];
        $column_child_change_rules      = [28, 33];
        $column_modify                  = 34;
        // 退款的
        $rru = new PlaneRefundRule();
        $cru = new PlaneChangeRule();
        $i   = 0;
        $rds = [];
        $rcs = [];
        foreach ($datas as $data) {
            if (!$data[$column_company_name]) {
                continue;
            }

            $company_name = $data[$column_company_name];
            if (Str::contains($company_name, [''])) {
                continue;
            }

            $carrier_code = $data[$column_carrier_code];
            if (mb_strlen($carrier_code) > 2) {
                continue;
            }
 

            $modify = ($data[$column_modify] ?? '') == '不可签转' ? 2 : 1;
            $rules  = $time_rules[$data[$column_rule]];

            $cabin_name  = $data[$column_cabin_name] ?? '';
            $cabin_codes = $data[$column_cabins] ?: '';
            $cabins      = $this->parse2Cabins($cabin_codes);
            $discount    = $data[$column_discount] ?: '';

            foreach ($rules as $rk => $rule) {
                foreach ($cabins as $cabin) {
                    if (Str::contains($cabin, '折扣')) {
                        preg_match('/(?<cabin>.+)\((?<discount>\d+%)(?<sign>.*)折扣\)/', $cabin, $res);
                        $dis  = $res['discount'] ?? '';
                        $sign = $res['sign'] ?? '';

                        if ($dis && !$discount) {
                            $has_and = Str::contains($sign, "及");
                            $sf      = "";
                            if (Str::contains($sign, "以上")) {
                                $sf = ">";
                                if ($has_and) {
                                    $sf = ">=";
                                }
                            } elseif (Str::contains($sign, "以下")) {
                                $sf = "<";
                                if ($has_and) {
                                    $sf = "<=";
                                }
                            }
                            $discount = "{$sf}{$dis}";
                        }
                        $cabin = $res['cabin'] ?? $cabin;
                    }
                    $i++;
//                    $this->info($i);
                    $cabin_code = $this->getCabin($cabin);
                    $rd         = [
                        'carrier_code' => $carrier_code,
                        'company_name' => $data[$column_company_name],
                        'cabin_name'   => $cabin_name,
                        'cabin_code'   => $cabin_code,
                        'airport_code' => '',
                        'airport_name' => $data[$column_airport_name] ?: '',
                        'ticket_type'  => $data[$column_ticket_type] ?: '',
                        'start'        => $rule['time']['start'],
                        'end'          => $rule['time']['end'],
                        'rule_desc'    => $rule['desc'],
                        'rate'         => $this->getRate($data[$rk + $column_adult_refund_rate_start], $data),
                        'discount'     => $discount,
                        'child_rate'   => $this->getRate($data[$rk + $column_child_refund_rate_start], $data),
                    ];
                    $rds[]      = $rd;
//                    $rru->add($rd);
                    $cd    = [
                        'carrier_code' => $carrier_code,
                        'company_name' => $data[$column_company_name],
                        'cabin_name'   => $cabin_name,
                        'cabin_code'   => $cabin_code,
                        'airport_code' => '',
                        'airport_name' => $data[$column_airport_name] ?: '',
                        'ticket_type'  => $data[$column_ticket_type] ?: '',
                        'start'        => $rule['time']['start'],
                        'end'          => $rule['time']['end'],
                        'rule_desc'    => $rule['desc'],
                        'rate'         => $this->getRate($data[$rk + $column_adult_change_rate_start], $data),
                        'discount'     => $data[$column_discount] ?: '',
                        'modify'       => $modify,
                        'child_rate'   => $this->getRate($data[$rk + $column_child_change_rate_start], $data),
                    ];
                    $rcs[] = $cd;
//                    $cru->add($cd);
                }
            }
        }
    }

    function parseTime(string $time): array
    {
        $times = explode('&', $time);
        $ret   = [
            'start' => '',
            'end'   => '',
        ];
        foreach ($times as $str) {
            if (Str::contains($str, '>')) {
                $ret['end'] = explode('>', $str)[1];
            }

            if (Str::contains($str, '<')) {
                $ret['start'] = explode('<', $str)[1];
            }
        }
        return $ret;
    }

    private function parse2Cabins($cabin_codes)
    {
        $cabins = [];
        if (!$cabin_codes) {
            return [''];
        }

        $parse  = function ($cabin_codes) {
            $rule   = '/(?<cabin1>[a-zA-Z]+)(?<f>\d)-(?<cabin2>[a-zA-Z]+)(?<l>\d)/s';
            $cabins = [];

            if (preg_match($rule, $cabin_codes, $match)) {
                $range = range($match['f'], $match['l']);
                if ($match['cabin1' == $match['cabin2']]) {
                    $cabins = collect($range)->map(fn($r) => $match['cabin2'].$r)->toArray();
                }

            }
            $splits      = ['/', '\\', '-'];
            $split       = '/';
            $cabin_codes = Str::replace($splits, $split, $cabin_codes);
            $exp         = explode($split, $cabin_codes);
            return array_unique(array_merge($cabins, $exp));
        };
        $cabins = $parse($cabin_codes);
        $this->info($cabin_codes.":".json_encode($cabins, 64 | 256));
        return $cabins;
    }

    /**
     */
    function getCabin(string $cabin): string
    {
        if (!$cabin || $cabin == '其他仓位' || $cabin == '无行李特惠') {
            return '';
        }
        preg_match('/[a-zA-Z0-9]+/', $cabin, $match);
        if (empty($match)) {
            return '';
        }
        if (!isset($match[0])) {
            return '';
        }
        return strtoupper($cabin);
    }

    function getRate(string|null $rate, $data = ''): string
    {
        if (is_null($rate)) {
            $rate = '';
        }

        return trim($rate);
    }
}
